package com.itany.jdbc.factory;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 陈华旺
 * @version 1.0
 * @date 2023年10月26日 10:43
 * @Description 对象工厂
 */
public class ObjectFactory {

    private static Map<String,Class> mapClass = new HashMap<>();
    private static Map<String,Object> mapObjs = new HashMap<>();
    private static Map<String,Object> mapProxy = new HashMap<>();

    static {
        try {
//            Properties p = new Properties();
//            p.load(ObjectFactory.class.getClassLoader().getResourceAsStream("obj.properties"));
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(
                            ObjectFactory.class.getClassLoader().getResourceAsStream("obj.properties")
                    )
            );
            String line = null;
            while ( (line = br.readLine()) != null ){
                String[] arr = line.split("=");
                if(arr.length == 2){
                    String key = arr[0];
                    String className = arr[1];
                    mapClass.put(key,Class.forName(className));
                }
            }
        } catch (Exception e){
            e.printStackTrace();
            throw new ExceptionInInitializerError("object factory init error:"+e.getMessage());
        }
    }

    public static <T> T getObj(String key) {
        try {
            Object obj = mapObjs.get(key);
            if(null==obj){
                Class objClass = mapClass.get(key);
                if(null==objClass){
                    throw new Exception();
                }else{
                    obj = objClass.newInstance();
                    mapObjs.put(key,obj);
                }
            }
            return (T) obj;
        } catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("factory object get error:"+e.getMessage());
        }
    }

    public static <T> T getProxy(String key, InvocationHandler handler){
        try {
            Object obj = mapProxy.get(key);
            if(null==obj){
                Class objClass = mapClass.get(key);
                if(null==objClass){
                    throw new Exception();
                }else{
//                    obj = objClass.newInstance();
                    obj = Proxy.newProxyInstance(
                            objClass.getClassLoader(),
                            objClass.getInterfaces(),
                            handler
                    );
                    mapProxy.put(key,obj);
                }
            }
            return (T) obj;
        } catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("factory object get error:"+e.getMessage());
        }
    }
}
